﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Filter colors
    /// </summary>
    public class ColorFilter : BaseImageFilter
    {
        protected byte m_nRed = 10;
        protected byte m_nGreen = 10;
        protected byte m_nBlue = 10;

        /// <summary>
        /// default constructor
        /// </summary>
        public ColorFilter()
        {
        }

        /// <summary>
        /// primary constructor
        /// </summary>
        /// <param name="_red"></param>
        /// <param name="_green"></param>
        /// <param name="_blue"></param>
        public ColorFilter(byte _red, byte _green, byte _blue)
        {
            m_nRed = _red;
            m_nGreen = _green;
            m_nBlue = _blue;
        }

        /// <summary>
        /// used by clone to create a deep copy
        /// </summary>
        /// <param name="_colorFilter"></param>
        internal ColorFilter(ColorFilter _colorFilter)
        {
            this.m_nRed = _colorFilter.m_nRed;
            this.m_nGreen = _colorFilter.m_nGreen;
            this.m_nBlue = _colorFilter.m_nBlue;
        }

        /// <summary>
        /// Gets or sets color
        /// </summary>
        public Color Color
        {
            get { return Color.FromArgb(m_nRed, m_nGreen, m_nBlue); }
            set 
            {
                m_nRed = value.R;
                m_nGreen = value.G;
                m_nBlue = value.B;
            }
        }

        /// <summary>
        /// Gets or sets red
        /// </summary>
        public byte Red
        {
            get { return m_nRed; }
            set { m_nRed = value; }
        }

        /// <summary>
        /// Gets or sets green
        /// </summary>
        public byte Green
        {
            get { return m_nGreen; }
            set { m_nGreen = value; }
        }

        /// <summary>
        /// Gets or sets blue
        /// </summary>
        public byte Blue
        {
            get { return m_nBlue; }
            set { m_nBlue = value; }
        }

        /// <summary>
        /// executes this filter
        /// </summary>
        /// <param name="_bitmap"></param>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap = _bitmap;

            // Copy the Bitmap into memory
            BitmapData bitmapData = bitmap.BitmapData; //bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);

            unsafe
            {
                byte* pScan0 = (byte*)bitmapData.Scan0;

                int offset = bitmapData.Stride - (bitmap.Width * bitmap.BytesPerPixelCount);//bitmapData.Stride - (bitmap.Width * 3);
                int pixel = 0;

                int nBytePerPixelCount = bitmap.BytesPerPixelCount;
                // Loop through all pixels and recolorize
                // red, green and blue values
                int nHeight = bitmap.Height;
                int nWidth = bitmap.Width;
                
                for (int y = 0; y < nHeight; ++y)
                {
                    for (int x = 0; x < nWidth; x++)
                    {
                        pixel = pScan0[2] + m_nRed;
                        pixel = Math.Max(pixel, 0);
                        pScan0[2] = (byte)Math.Min(255, pixel);

                        pixel = pScan0[1] + m_nGreen;
                        pixel = Math.Max(pixel, 0);
                        pScan0[1] = (byte)Math.Min(255, pixel);

                        pixel = pScan0[0] + m_nBlue;
                        pixel = Math.Max(pixel, 0);
                        pScan0[0] = (byte)Math.Min(255, pixel);

                        pScan0 += nBytePerPixelCount;
                    }
                    pScan0 += offset;
                }
            }

            // Unlock Bitmap from memory
            return _bitmap;
        }

        /// <summary>
        /// create a deep copy
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new ColorFilter(this);
        }
    }   
}
